package com.ruiyu.workers

import com.intellij.json.psi.JsonFile
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiManager
import com.ruiyu.file.FileHelpers
import com.ruiyu.helper.YamlHelper
import java.util.regex.Pattern

/**
 * User: zhangruiyu
 * Date: 2019/12/22
 * Time: 15:34
 */
class FileGenerator(private val project: Project) {

    private var psiManager: PsiManager? = null
    private var documentManager: PsiDocumentManager? = null

    init {
        try {
            psiManager = PsiManager.getInstance(project)
        } catch (ignored: Throwable) {
        }
        try {
            documentManager = PsiDocumentManager.getInstance(project)
        } catch (ignored: Throwable) {
        }
    }

    fun generate() {
        if (!YamlHelper.shouldActivateFor(project)) {
            return
        }
        psiManager?.let { psiManager ->
            documentManager?.let { documentManager ->
                val builder = StringBuilder()
                builder.append("// ignore_for_file: non_constant_identifier_names\n// ignore_for_file: camel_case_types\n// ignore_for_file: prefer_single_quotes\n\n")
                builder.append("// This file is automatically generated. DO NOT EDIT, all your changes would be lost.\n")
//                builder.append(JsonConvertContent)
//                builder.append("\n")
                builder.append(getJSONFieldContent(project))
                val jsonConvertContent = builder.toString()
                FileHelpers.getJsonConvertJsonFiledFile(project) { file ->
                    psiManager.findFile(file)?.let { dartFile ->
                        documentManager.getDocument(dartFile)?.let { document ->
                            if (document.text != jsonConvertContent) {
                                document.setText(jsonConvertContent)
                                documentManager.commitDocument(document)
                            }
                        }
                    }
                }
            }
        }
        /*psiManager?.let { psiManager ->
            documentManager?.let { documentManager ->
                val valuesFolder = FileHelpers.getValuesFolder(project)
                stringFiles(valuesFolder)?.let { files ->
                    if (files.isEmpty()) {
                        createFileForLang("en", psiManager, documentManager, valuesFolder)?.let {
                            files.add(it)
                        } ?: run {
                            return@generate
                        }
                    }

                    val data = HashMap<String, HashMap<String, String>>()

                    files.forEach {
                        val lang = it.nameWithoutExtension.substringAfter("_")
                        val json = psiManager.findFile(it) as JsonFile
                        data[lang] = getStringFromFile(json) ?: HashMap()
                    }

                    val builder = StringBuilder()
                    builder.append(i18nFileImports)
                    builder.append("// ignore_for_file: non_constant_identifier_names\n// ignore_for_file: camel_case_types\n// ignore_for_file: prefer_single_quotes\n\n")
                    builder.append("// This file is automatically generated. DO NOT EDIT, all your changes would be lost.\n")
                    appendSClass(data["en"]!!, builder)

                    val className = "\$en"
                    data.keys.forEach {
                        if (it == "en") builder.append("class $className extends S {\n  const $className();\n}\n\n")
                        else appendLangClass(it, data, builder)
                    }

                    appendDelegateClass(data, builder)

                    val i18nFile = builder.toString()

                    FileHelpers.getI18nFile(project) { file ->
                        file?.let { file ->
                            psiManager.findFile(file)?.let { dartFile ->
                                documentManager.getDocument(dartFile)?.let { document ->
                                    if (document.text != i18nFile) {
                                        document.setText(i18nFile)
                                        documentManager.commitDocument(document)
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }*/
    }

    companion object {

        // @formatter:off
        private const val JsonConvertContent =
                """class JsonConvert<T> {
  T fromJson(Map<String, dynamic> json) {
    return this as T;
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    print(this.runtimeType);
    return data;
  }
}"""

        fun getJSONFieldContent(project: Project): String {
            val isNullSafe = YamlHelper.getPubSpecConfig(project)?.isNullSafe ?: true
            return if (isNullSafe) """
class JSONField {
  //Specify the parse field name
  final String? name;

  //Whether to participate in toJson
  final bool? serialize;
  
  //Whether to participate in fromMap
  final bool? deserialize;

  const JSONField({this.name, this.serialize, this.deserialize});
}
""" else """
class JSONField {
  //Specify the parse field name
  final String name;

  //Whether to participate in toJson
  final bool serialize;
  
  //Whether to participate in fromMap
  final bool deserialize;

  const JSONField({this.name, this.serialize, this.deserialize});
}
"""
        }

    }
}